package service

import (
	"context"
	"dy/internal/api/store"
	"dy/internal/models"
	"dy/pkg/util"
	"errors"
	"time"
)

type VideoSrv interface {
	Add(ctx context.Context, param map[string]interface{}) error
	List(ctx context.Context, authorId int) ([]map[string]interface{}, int, error)
}

type videoService struct {
	store store.Factory
}

func (u *videoService) Add(ctx context.Context, param map[string]interface{}) error {
	var video *models.DyVideo
	err := util.StructTo(&param, &video)
	if err != nil {
		return err
	}

	_, err = u.store.Video().Create(ctx, video)
	if err != nil {
		return err
	}
	return nil
}

func (u *videoService) List(ctx context.Context, authorId int) ([]map[string]interface{}, int, error) {
	search := map[string]interface{}{}
	if authorId != 0 {
		search["author_id"] = authorId
	}

	list, _, err := u.store.Video().Find(ctx, search, "add_time", "")
	if err != nil {
		return nil, 0, err
	}
	result := make([]map[string]interface{}, 0)
	var nextTime int64
	nextTime = 0
	for _, element := range list {
		dyUser, flag, err := u.store.User().Get(ctx, &models.DyUser{Id: element.AuthorId})
		if flag == false {
			return nil, 0, errors.New("the author is not exist")
		}
		if err != nil {
			return nil, 0, err
		}

		_, followCount, err := u.store.Relation().Find(ctx, map[string]interface{}{"user_id": dyUser.Id}, "add_time", "")
		if err != nil {
			return nil, 0, err
		}
		_, followerCount, err := u.store.Relation().Find(ctx, map[string]interface{}{"follow_id": dyUser.Id}, "add_time", "")
		if err != nil {
			return nil, 0, err
		}
		_, isFollow, err := u.store.Relation().Get(ctx, &models.DyUserRelation{UserId: authorId, FollowId: dyUser.Id})
		if err != nil {
			return nil, 0, err
		}

		user := map[string]interface{}{
			"id":             dyUser.Id,
			"name":           dyUser.Name,
			"follow_count":   followCount,
			"follower_count": followerCount,
			"is_follow":      isFollow,
		}

		_, favoriteCount, err := u.store.Favorite().Find(ctx, map[string]interface{}{"video_id": element.Id}, "add_time", "")
		if err != nil {
			return nil, 0, err
		}
		_, commentCount, err := u.store.Comment().Find(ctx, map[string]interface{}{"video_id": element.Id}, "add_time", "")
		if err != nil {
			return nil, 0, err
		}
		_, isFavorite, err := u.store.Favorite().Get(ctx, &models.DyLikeRelation{UserId: authorId, VideoId: element.Id})
		if flag == false {
			return nil, 0, errors.New("the author is not exist")
		}
		if err != nil {
			return nil, 0, err
		}

		video := map[string]interface{}{
			"id":             element.Id,
			"author":         user,
			"play_url":       element.PlayUrl,
			"cover_url":      element.CoverUrl,
			"favorite_count": favoriteCount,
			"comment_count":  commentCount,
			"is_favorite":    isFavorite,
			"title":          element.Title,
		}
		if nextTime == 0 || nextTime > time.Time(element.AddTime).Unix() {
			nextTime = time.Time(element.AddTime).Unix()
		}

		result = append(result, video)
	}

	return result, int(nextTime), nil
}

func NewVideoService(s *service) VideoSrv {
	return &videoService{
		store: s.store,
	}
}
